package com.douxg.fastCoding.db;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.douxg.fastCoding.web.entity.Project;
import com.douxg.fastCoding.web.eo.DbInfoEo;
import com.douxg.fastCoding.web.service.ProjectService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * @Description
 * @Auther douxg
 * @Date 2020/7/20 23:42
 */
@Component
public class ConfigManager {
    private static ProjectService projectService;

    @Resource
    public void setProjectService(ProjectService projectService) {
        ConfigManager.projectService = projectService;
    }

    public static ConfigEO getConfig(DbInfoEo dbInfoEo, List<ColumnsEO> columnsEos) {
        ConfigEO resultConfig = getDefaultConfig();
        Long projectId = dbInfoEo.getProjectId();
        String configStr;
        CopyOptions copyOptions = CopyOptions.create();
        copyOptions.setIgnoreNullValue(true);
        if (projectId != null) {
            Project project = projectService.getById(projectId);
            configStr = project.getConfig();
            if (StrUtil.isNotBlank(configStr)) {
                Config config = JSON.parseObject(configStr, Config.class);
                BeanUtil.copyProperties(config, resultConfig, copyOptions);
            }
        }
        configStr = dbInfoEo.getConfig();
        if (StrUtil.isNotBlank(configStr)) {
            Config config = JSON.parseObject(configStr, Config.class);
            BeanUtil.copyProperties(config, resultConfig, copyOptions);
        }
        handlePageQueryOrderBy(dbInfoEo, columnsEos, resultConfig);
        return resultConfig;
    }

    public static ConfigEO getDefaultConfig() {
        ConfigEO configEO = new ConfigEO();
        configEO.setProjectPackage("com.douxg.yuyan.web");
        configEO.setEntityPackage("entity");
        configEO.setDtoPackage("dto");
        configEO.setDtoSuffix("Dto");
        configEO.setVoPackage("vo");
        configEO.setVoSuffix("Vo");
        configEO.setMapperPackage("mapper");
        configEO.setMapperSuffix("Mapper");
        configEO.setMapperXmlPath("mapper");
        configEO.setServicePackage("service");
        configEO.setServiceImplPackage("service.impl");
        configEO.setServiceSuffix("Service");
        configEO.setServiceImplSuffix("ServiceImpl");
        configEO.setControllerPackage("controller");
        configEO.setControllerSuffix("Controller");
        configEO.setServiceMethodPrefix("my");
        configEO.setResultName("Result");
        configEO.setResultPackage(".spring.vo");
        configEO.setTimeRoundQueryColumn(Arrays.asList("create_time"));
        configEO.setPageQueryOrderBy("create_time");
        return configEO;
    }

    /**
     * 默认分页查询的排序字段
     * 如果为空，默认主键
     * 如果没有主键默认第一个字段
     *
     * @param dbInfoEo
     * @param columnsEos
     * @param configEO
     */
    private static void handlePageQueryOrderBy(DbInfoEo dbInfoEo, List<ColumnsEO> columnsEos, ConfigEO configEO) {
        String pageQueryOrderBy = configEO.getPageQueryOrderBy();
        if (!containsField(pageQueryOrderBy, columnsEos)) {
            for (ColumnsEO columnsEo : columnsEos) {
                if (columnsEo.getPriKey()) {
                    pageQueryOrderBy = columnsEo.getColumnName();
                    break;
                }
            }
        }
        pageQueryOrderBy = pageQueryOrderBy == null ? columnsEos.get(0).getColumnName() : pageQueryOrderBy;
        configEO.setPageQueryOrderBy(pageQueryOrderBy);
    }

    /**
     * 判断字段集合中是否包含某个字段
     *
     * @param field
     * @param columnsEos
     * @return
     */
    public static boolean containsField(String field, List<ColumnsEO> columnsEos) {
        if (field != null) {
            for (ColumnsEO columnsEo : columnsEos) {
                if (columnsEo.getColumnName().equals(field)) {
                    return true;
                }
            }
        }
        return false;
    }
}
